package slidingpenguins.slideshow.model {
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.utils.IDataInput;
	import flash.utils.IDataOutput;
	
	import nochump.util.zip.ZipEntry;
	import nochump.util.zip.ZipFile;
	import nochump.util.zip.ZipOutput;
	
	import slidingpenguins.utils.imagecache.CachedImage;
	import slidingpenguins.utils.imagecache.ImageCache;

	public class SlideshowFile {
		public static const SLIDESHOW_XML_FILE_NAME:String = "slideshow.xml";
		public static const SLIDESHOW_IMAGE_DIRECTORY:String = "images";
		public static const SLIDESHOW_INLINE_URI_SCHEMA:String = "slideshow://";
		
		private var cache:ImageCache;
		private var _slideshow:Slideshow;
		
		public function SlideshowFile(cache:ImageCache) {
			this.cache = cache;			
		}
		
		public static function loadFromStream(source:IDataInput, cache:ImageCache):SlideshowFile {
			var result:SlideshowFile = new SlideshowFile(cache);
			
			var slideshowFile:ZipFile = new ZipFile(source);
			
			if (slideshowFile.getEntry(SLIDESHOW_XML_FILE_NAME) == null) {
				throw new SlideshowFileParsingError();
			}
			
			result._slideshow = Slideshow.loadFromXML(new XML(slideshowFile.getInput(slideshowFile.getEntry(SLIDESHOW_XML_FILE_NAME)).toString()));
			
			for each (var entry:ZipEntry in slideshowFile.entries) {
				if (entry.name.match(new RegExp("^" + SLIDESHOW_IMAGE_DIRECTORY + "/.+")).length > 0) {
					cache.addImage(SLIDESHOW_INLINE_URI_SCHEMA + entry.name, slideshowFile.getInput(entry), true);
				}
			}
			
			return result;
		}
		
		public function saveToStream(output:IDataOutput):void {
			var slideshowFile:ZipOutput = new ZipOutput();
			
			var slideshowInBytes:ByteArray = new ByteArray();
			slideshow.saveToXML(slideshowInBytes);
			
			slideshowFile.putNextEntry(new ZipEntry(SLIDESHOW_XML_FILE_NAME));
			slideshowFile.write(slideshowInBytes);
			slideshowFile.closeEntry();
			
			for each (var slide:Slide in slideshow.slides) {
				for each (var image:Image in slide.images) {
					if (image.isInline) {
						var cachedImage:CachedImage = cache.getImage(image.slideshowURI);
						
						if (cachedImage.isReady) {
							slideshowFile.putNextEntry(new ZipEntry(image.uri));
							slideshowFile.write(cachedImage.bytes);
							slideshowFile.closeEntry();
						}
					}
				}
			}
			
			slideshowFile.finish();
			
			output.writeBytes(slideshowFile.byteArray);
		}
		
		public function get slideshow():Slideshow {
			return _slideshow;
		}
		
		public function deleteInlineImage(image:Image):void {
			cache.makeDeletable(image.slideshowURI);
			cache.deleteImage(image.slideshowURI);
		}
		
		private function setInlineURI(image:Image, uri:String):void {
			image.uri = uri;
			image.isInline = true;
		}
		
		public function makeImageInline(image:Image):void {
			slideshow.incrementLastInlineImageID();
			var newURI:String = SLIDESHOW_IMAGE_DIRECTORY + "/" + slideshow.lastInlineImageID;

			var cachedImage:CachedImage = cache.getImage(image.slideshowURI, true);
			cache.createAlias(image.slideshowURI, newURI);
			
			if (!cachedImage.isReady) {
				cachedImage.addEventListener(Event.COMPLETE, function(event:Event):void {
					setInlineURI(image, newURI);
				});
			} else {
				setInlineURI(image, newURI);
			}
		}
	}
}
